package com.itheima.api.user;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mapper.user.UmsRoleMapper;
import com.itheima.vo.domain.AjaxResult;
import com.itheima.vo.domain.TableDataInfo;
import com.itheima.vo.dto.RoleDto;
import com.itheima.vo.pojo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 后台用户角色管理业务层实现类
 */
@DubboService
public class UmsRoleServiceImpl extends ServiceImpl<UmsRoleMapper, UmsRole> implements UmsRoleService {

    //订阅角色菜单关联服务
    @DubboReference
    private UmsRoleMenuRelationService menuRelationService;

    //订阅角色资源关联服务
    @DubboReference
    private UmsRoleResourceRelationService resourceRelationService;

    //订阅角色权限关联服务
    @DubboReference
    private UmsRolePermissionRelationService permissionRelationService;

    //订阅菜单服务
    @DubboReference
    private UmsMenuService menuService;

    //订阅资源服务
    @DubboReference
    private UmsResourceService resourceService;

    /**
     * 给角色分配菜单
     * @param roleDto 封装角色id,菜单ids
     * @return 提示信息
     */
    @Transactional
    @Override
    public AjaxResult allocMenu(RoleDto roleDto) {
        Long roleId = roleDto.getRoleId();
        if (roleId==null) return AjaxResult.error("角色不存在");
        List<Long> menuIds = roleDto.getMenuIds();
        if(menuIds==null || menuIds.size()==0) return AjaxResult.error("菜单不存在");
        //删除角色对应的目录
        LambdaQueryWrapper<UmsRoleMenuRelation> menu=new LambdaQueryWrapper<>();
        menu.eq(UmsRoleMenuRelation::getRoleId,roleId);
        menuRelationService.remove(menu);
        //封装存储数据
        List<UmsRoleMenuRelation> relations=menuIds.stream().map(menuId->{
            UmsRoleMenuRelation relation=new UmsRoleMenuRelation();
            relation.setRoleId(roleId);
            relation.setMenuId(menuId);
            return relation;
        }).collect(Collectors.toList());
        //存储角色菜单关联信息
        menuRelationService.saveBatch(relations);
        return AjaxResult.success();
    }

    /**
     *给角色分配资源
     * @param roleDto 封装角色id,资源ids
     * @return 提示信息
     */
    @Transactional
    @Override
    public AjaxResult allocResource(RoleDto roleDto) {
        Long roleId = roleDto.getRoleId();
        if (roleId==null) return AjaxResult.error("角色不存在");
        List<Long> resourceIds = roleDto.getResourceIds();
        if(resourceIds==null || resourceIds.size()==0) return AjaxResult.error("资源不存在");
        //删除角色对应的资源
        LambdaQueryWrapper<UmsRoleResourceRelation> resource=new LambdaQueryWrapper<>();
        resource.eq(UmsRoleResourceRelation::getRoleId,roleId);
        resourceRelationService.remove(resource);
        //封装存储数据
        List<UmsRoleResourceRelation> relations=resourceIds.stream().map(resourceId->{
            UmsRoleResourceRelation relation=new UmsRoleResourceRelation();
            relation.setRoleId(roleId);
            relation.setResourceId(resourceId);
            return relation;
        }).collect(Collectors.toList());
        //存储角色资源关系
        resourceRelationService.saveBatch(relations);
        return AjaxResult.success();
    }


    /**
     * 批量删除角色
     * @param ids 角色id
     * 删除多个表的数据,开启事务
     */
    @Transactional
    @Override
    public void deleteRoles(List<Long> ids) {
        //删除角色对应的目录
        LambdaQueryWrapper<UmsRoleMenuRelation> menu=new LambdaQueryWrapper<>();
        menu.in(UmsRoleMenuRelation::getRoleId,ids);
        menuRelationService.remove(menu);
        //删除角色对应的资源
        LambdaQueryWrapper<UmsRoleResourceRelation> resource=new LambdaQueryWrapper<>();
        resource.in(UmsRoleResourceRelation::getRoleId,ids);
        resourceRelationService.remove(resource);
        //删除角色对应的权限
        LambdaQueryWrapper<UmsRolePermissionRelation> permission=new LambdaQueryWrapper<>();
        permission.in(UmsRolePermissionRelation::getRoleId,ids);
        permissionRelationService.remove(permission);
        //删除角色
        this.removeByIds(ids);
    }

    /**
     * 根据角色名称分页获取角色列表
     * @param keyword  角色名称
     * @param pageNum  当前页码
     * @param pageSize  当前页条目数
     * @return  分页查询对象
     */
    @Override
    public TableDataInfo getRoleList(String keyword, Integer pageNum, Integer pageSize) {
        Page<UmsRole> page=new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<UmsRole> lqw=new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotEmpty(keyword),UmsRole::getName,keyword);
        this.page(page,lqw);
        return new TableDataInfo(page.getRecords(),pageNum,pageSize,page.getTotal(),page.getPages());
    }

    /**
     * 获取角色相关菜单
     * @param roleId 角色id
     * @return  菜单数据
     */
    @Override
    public List<UmsMenu> getRoleMenuList(Long roleId) {
        //获取菜单id
        LambdaQueryWrapper<UmsRoleMenuRelation> urr=new LambdaQueryWrapper<>();
        urr.eq(UmsRoleMenuRelation::getRoleId,roleId);
        List<UmsRoleMenuRelation> menuRelations = menuRelationService.list(urr);
        List<Long> menuIds = CollUtil.getFieldValues(menuRelations, "menuId", Long.class);
        //根据菜单id查询菜单列表并返回
        return menuService.listByIds(menuIds);
    }

    /**
     *获取角色相关资源
     * @param roleId 角色id
     * @return 资源集合
     */
    @Override
    public List<UmsResource> getListResource(Long roleId) {
        //获取资源id
        LambdaQueryWrapper<UmsRoleResourceRelation> urr=new LambdaQueryWrapper<>();
        urr.eq(UmsRoleResourceRelation::getRoleId,roleId);
        List<UmsRoleResourceRelation> resourceRelations = resourceRelationService.list(urr);
        List<Long> resourceIds = CollUtil.getFieldValues(resourceRelations, "resourceId", Long.class);
        //根据菜单id查询资源集合并返回
        return resourceService.listByIds(resourceIds);

        //1234123412412351234521
    }


    /**
     *获取当前登录用户角色,菜单
     * @param roleIds 当前登录用户角色id
     * @return  用户角色,用户菜单
     */
    @Override
    public Map<String, Object> getCurrentLoginMenus(List<Long> roleIds) {
        //获取菜单id
        LambdaQueryWrapper<UmsRoleMenuRelation> roleMenu=new LambdaQueryWrapper<>();
        roleMenu.in(UmsRoleMenuRelation::getRoleId,roleIds);
        List<UmsRoleMenuRelation> menuRelations = menuRelationService.list(roleMenu);
        List<Long> menuIds = CollUtil.getFieldValues(menuRelations, "menuId", Long.class);
        //获取菜单列表
        List<UmsMenu> menus = menuService.listByIds(menuIds);
        Map<String,Object> map=new HashMap<>();
        map.put("menus",menus);
        return map;
    }
}
